/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.modulelink.mvc;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.jianggujin.modulelink.JModuleContext;
import com.jianggujin.modulelink.mvc.upload.JMultipartActionContext;

/**
 * 模块的执行者上下文
 * 
 * @author jianggujin
 *
 */
public interface JActionContext extends JMultipartActionContext {
    /**
     * 获得模块上下文
     * 
     * @return
     */
    JModuleContext getModuleContext();

    /**
     * 获得请求参数
     * 
     * @param name
     * @return
     */
    String getPara(String name);

    /**
     * 获得请求参数
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    String getPara(String name, String defaultValue);

    /**
     * 获得请求参数
     * 
     * @param name
     * @return
     */
    String[] getParaValues(String name);

    /**
     * 获得整型请求参数
     * 
     * @param name
     * @return
     */
    Integer getParaToInt(String name);

    /**
     * 获得整型请求参数
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    Integer getParaToInt(String name, Integer defaultValue);

    /**
     * 获得长整型请求参数
     * 
     * @param name
     * @return
     */
    Long getParaToLong(String name);

    /**
     * 获得长整型请求参数
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    Long getParaToLong(String name, Long defaultValue);

    /**
     * 获得布尔型请求参数
     * 
     * @param name
     * @return
     */
    Boolean getParaToBoolean(String name);

    /**
     * 获得布尔型请求参数
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    Boolean getParaToBoolean(String name, Boolean defaultValue);

    /**
     * 获得日期型请求参数
     * 
     * @param name
     * @return
     */
    Date getParaToDate(String name);

    /**
     * 获得日期型请求参数
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    Date getParaToDate(String name, Date defaultValue);

    /**
     * 将请求参数转换为指定的JavaBean
     * 
     * @param clazz
     * @return
     */
    <T> T getParaToBean(Class<T> clazz);

    /**
     * 将请求参数转换为指定的JavaBean
     * 
     * @param clazz
     * @param skipConvertError
     * @return
     */
    <T> T getParaToBean(Class<T> clazz, boolean skipConvertError);

    /**
     * 获得指定类型请求参数
     * 
     * @param name
     * @param clazz
     * @return
     */
    <T> T getPara(String name, Class<T> clazz);

    /**
     * 获得指定类型请求参数
     * 
     * @param name
     * @param clazz
     * @param defaultValue
     * @return
     */
    <T> T getPara(String name, Class<T> clazz, T defaultValue);

    /**
     * 获得所有请求参数
     * 
     * @return
     */
    Map<String, ?> getParaMap();

    /**
     * 获得请求参数名称
     * 
     * @return
     */
    Enumeration<String> getParaNames();

    /**
     * 设置请求参数，使用此方法需谨慎
     * 
     * @param paraMap
     */
    void setParaMap(Map<String, ?> paraMap);

    /**
     * 保持请求参数，会将请求参数回设变成{@link HttpServletRequest}属性
     * 
     * @return
     */
    JActionContext keepPara();

    /**
     * 保持指定的请求参数，会将请求参数回设变成{@link HttpServletRequest}属性
     * 
     * @return
     */
    JActionContext keepPara(String... names);

    /**
     * 判断请求参数是否存在
     * 
     * @param paraName
     * @return
     */
    boolean isParaExists(String paraName);

    /**
     * 获得所有路径参数
     * 
     * @return
     */
    String[] getPathParas();

    /**
     * 获得路径参数个数
     * 
     * @return
     */
    int getPathCount();

    /**
     * 获得路径参数
     * 
     * @param pos
     * @return
     */
    String getPathPara(int pos);

    /**
     * 获得整型路径参数
     * 
     * @param pos
     * @return
     */
    Integer getPathParaToInt(int pos);

    /**
     * 获得长整型路径参数
     * 
     * @param pos
     * @return
     */
    Long getPathParaToLong(int pos);

    /**
     * 获得布尔型路径参数
     * 
     * @param pos
     * @return
     */
    Boolean getPathParaToBoolean(int pos);

    /**
     * 获得指定类型的路径参数
     * 
     * @param pos
     * @param clazz
     * @return
     */
    <T> T getPathPara(int pos, Class<T> clazz);

    /**
     * 获得Cookie
     * 
     * @param name
     * @param defaultValue
     * @return
     */
    String getCookie(String name, String defaultValue);

    /**
     * 获得Cookie
     * 
     * @param name
     * @return
     */
    String getCookie(String name);

    /**
     * 设置Cookie
     * 
     * @param cookie
     * @return
     */
    JActionContext setCookie(Cookie cookie);

    /**
     * 移除Cookie
     * 
     * @param name
     * @return
     */
    JActionContext removeCookie(String name);

    /**
     * 设置{@link HttpServletRequest}属性
     * 
     * @param name
     * @param value
     * @return
     */
    JActionContext setAttr(String name, Object value);

    /**
     * 获得{@link HttpServletRequest}属性
     * 
     * @param name
     * @return
     */
    Object getAttr(String name);

    /**
     * 设置{@link HttpSession}属性
     * 
     * @param name
     * @param value
     * @return
     */
    JActionContext setSessionAttr(String name, Object value);

    /**
     * 获得{@link HttpSession}属性
     * 
     * @param name
     * @return
     */
    Object getSessionAttr(String name);

    /**
     * 设置{@link ServletContext}属性
     * 
     * @param name
     * @param value
     * @return
     */
    JActionContext setContextAttr(String name, Object value);

    /**
     * 获得{@link ServletContext}属性
     * 
     * @param name
     * @return
     */
    Object getContextAttr(String name);

    /**
     * 获得请求头
     * 
     * @param name
     * @return
     */
    String getHeader(String name);

    /**
     * 获得{@link HttpServletRequest}对象
     * 
     * @return
     */
    HttpServletRequest getRequest();

    /**
     * 获得{@link HttpServletResponse}对象
     * 
     * @return
     */
    HttpServletResponse getResponse();

    /**
     * 获得{@link HttpSession}对象
     * 
     * @return
     */
    HttpSession getSession();

    /**
     * 获得{@link HttpSession}对象
     * 
     * @param create
     * @return
     */
    HttpSession getSession(boolean create);

    /**
     * 获得{@link ServletContext}对象
     * 
     * @return
     */
    ServletContext getContext();

    /**
     * 获得请求数据
     * 
     * @return
     * @throws IOException
     */
    byte[] getRequestData() throws IOException;

    /**
     * 获得请求体，将请求输入流转换为字符串
     * 
     * @return
     * @throws IOException
     */
    String getRequestBody() throws IOException;

    /**
     * 获得请求体，将请求输入流转换为字符串
     * 
     * @param charset
     * @return
     * @throws IOException
     */
    String getRequestBody(String charset) throws IOException;

    /**
     * 获得JSON请求数据
     * 
     * @param clazz
     * @return
     * @throws IOException
     */
    <T> T getRequestJson(Class<T> clazz) throws IOException;

    /**
     * 获得JSON请求数据
     * 
     * @param clazz
     * @param charset
     * @return
     */
    <T> T getRequestJson(Class<T> clazz, String charset);

    /**
     * 获得XML请求数据
     * 
     * @param clazz
     * @return
     * @throws IOException
     */
    <T> T getRequestXml(Class<T> clazz) throws IOException;

    /**
     * 获得XML请求数据
     * 
     * @param clazz
     * @param charset
     * @return
     */
    <T> T getRequestXml(Class<T> clazz, String charset);

    /**
     * 文本响应
     * 
     * @param txt
     * @throws ServletException
     * @throws IOException
     */
    void renderText(String txt) throws IOException, ServletException;

    /**
     * 请求转发
     * 
     * @param path
     * @throws ServletException
     * @throws IOException
     */
    void renderDispatcher(String path) throws IOException, ServletException;

    /**
     * 重定向
     * 
     * @param path
     * @throws ServletException
     * @throws IOException
     */
    void renderRedirect(String path) throws IOException, ServletException;

    /**
     * 异常响应
     * 
     * @param code
     * @throws IOException
     * @throws ServletException
     */
    void renderError(int code) throws IOException, ServletException;

    /**
     * JSON响应
     * 
     * @param json
     * @throws IOException
     * @throws ServletException
     */
    void renderJson(Object json) throws IOException, ServletException;

    /**
     * XML响应
     * 
     * @param xml
     * @throws IOException
     * @throws ServletException
     */
    void renderXml(Object xml) throws IOException, ServletException;
}
